﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Web;
using System.Xml;
using System.Xml.Serialization;

namespace EmailHtmlTemplateMVC.Services
{
    public partial class EmailService
    {

        public static void SendEmailContacto(string Nombre, string Email, string Asunto, string Consulta)
        {
            try
            {
                string htmlTemplate = string.Empty;
                EmailConfiguration emailConfiguration = new EmailConfiguration();
                Email email = emailConfiguration.GetEmailConfiguration("Contacto");

                if (email == null)
                    throw new Exception("No se ha encontrado la configuración para: Password");

                string pathTemplate = string.Format(@"{0}\{1}",
                                        ConfigurationManager.AppSettings["pathTemplateHTML"],
                                        email.Contenido.Nombre);

                using (StreamReader reader = new StreamReader(@pathTemplate))
                {
                    htmlTemplate = reader
                                    .ReadToEnd()
                                    .Replace("[NOMBRE]", Nombre)
                                    .Replace("[EMAIL]", Email)
                                    .Replace("[ASUNTO]", Asunto)
                                    .Replace("[CONSULTA]", Consulta);
                }
                SendEmail
                (
                    configurationName: "Contacto",
                    //nombreDestinatario: apellido, //other name user target   || otro nombre de destinatario
                    //emailDestinatario: emailDestinatario, //other target email || otro email de destinatario
                    textoHtml: htmlTemplate
                );
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }

        public static void SendEmail(string configurationName, string nombreDestinatario = "", string emailDestinatario = "", string textoHtml = "")
        {
            try
            {
                SmtpClient server = new SmtpClient();
                MailMessage mensajeEmail = new MailMessage();
                EmailConfiguration emailConfiguration = new EmailConfiguration();

                Email email = emailConfiguration.GetEmailConfiguration(configurationName);

                if (email == null)
                    throw new Exception("No se ha encontrado la configuración para: " + configurationName);

                if (string.IsNullOrEmpty(textoHtml))
                {
                    string pathTemplate = string.Format(@"{0}\{1}", email.Contenido.Ruta, email.Contenido.Nombre);
                    using (StreamReader reader = new StreamReader(@pathTemplate))
                    {
                        textoHtml = reader.ReadToEnd();
                    }
                }
                AlternateView htmlView = AlternateView.CreateAlternateViewFromString(textoHtml, null, "text/html");

                mensajeEmail.AlternateViews.Add(htmlView);

                mensajeEmail.IsBodyHtml = true;
                mensajeEmail.Subject = email.Asunto;
                mensajeEmail.From = new MailAddress(email.Origen.Email, email.Origen.Nombre);
                if (!string.IsNullOrEmpty(emailDestinatario))
                {
                    mensajeEmail.To.Add(new MailAddress(emailDestinatario, nombreDestinatario));
                }
                foreach (var item in email.Destinos.Destino.Where(e => e.Tipo == "TO"))
                {
                    mensajeEmail.To.Add(new MailAddress(item.Email, item.Nombre));
                }
                foreach (var item in email.Destinos.Destino.Where(e => e.Tipo == "CC"))
                {
                    mensajeEmail.CC.Add(new MailAddress(item.Email, item.Nombre));
                }
                foreach (var item in email.Destinos.Destino.Where(e => e.Tipo == "BCC"))
                {
                    mensajeEmail.Bcc.Add(new MailAddress(item.Email, item.Nombre));
                }
                server.Send(mensajeEmail);
            }
            catch (Exception exception)
            {
                throw exception;
            }
        }

        public class EmailConfiguration
        {
            public EmailConfiguration()
            {
                if (HttpContext.Current.Session["EmailConfiguration"] == null)
                {
                    LoadPageConfiguration();
                }
                else
                {
                    FileSystemWatcher watcher = new FileSystemWatcher();
                    watcher.Path = ConfigurationManager.AppSettings["pathTemplateXML"];
                    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
                       | NotifyFilters.FileName | NotifyFilters.DirectoryName;
                    watcher.Filter = "Email.xml";
                    watcher.Changed += new FileSystemEventHandler(OnChanged);
                    // Begin watching.
                    watcher.EnableRaisingEvents = true;
                }
            }

            public Email GetEmailConfiguration(string nombre)
            {
                try
                {
                    Dictionary<string, Email> emails =
                        (Dictionary<string, Email>)HttpContext.Current.Session["EmailConfiguration"];
                    return emails[nombre];
                }
                catch (Exception)
                {
                    return null;
                }
            }

            private void OnChanged(object sender, FileSystemEventArgs e)
            {
                LoadPageConfiguration();
            }

            private void LoadPageConfiguration()
            {
                Emails emails = null;
                Dictionary<string, Email> paginasDic = new Dictionary<string, Email>();
                string pathFilePagina = string.Format(@"{0}\{1}", ConfigurationManager.AppSettings["pathTemplateXML"], "Email.xml");
                using (XmlReader reader = XmlReader.Create(@pathFilePagina))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(Emails));
                    emails = (Emails)serializer.Deserialize(reader);
                }
                foreach (var item in emails.Email)
                {
                    paginasDic.Add(item.Nombre, item);
                }
                HttpContext.Current.Session["EmailConfiguration"] = paginasDic;
            }
        }
    }
}